package com.hy;

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.loader.LaunchedURLClassLoader;
import org.springframework.boot.loader.archive.JarFileArchive;
import org.springframework.boot.loader.util.SystemPropertyUtils;
import org.springframework.boot.web.servlet.ServletComponentScan;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.jar.JarFile;
import java.util.jar.Manifest;

@SpringBootApplication
@EnableDubbo
@ServletComponentScan //用于扫描所有的Servlet、filter、listener
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class DubboNacosProviderAPPlication {

	public static void main(String[] args) throws URISyntaxException, IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
		if(classLoader instanceof LaunchedURLClassLoader){
			LaunchedURLClassLoader launchedURLClassLoader = (LaunchedURLClassLoader)classLoader;
			//已加载的jars
			List<URL> hasLoaderJars = Arrays.asList(launchedURLClassLoader.getURLs());
			//classPath jars
			List<URL> classPathJars = new ArrayList<>();
			//待加载的jars
			List<URL> needLoaderJars = new ArrayList<>();


			ProtectionDomain protectionDomain = LaunchedURLClassLoader.class.getProtectionDomain();
			CodeSource codeSource = protectionDomain.getCodeSource();
			URI location = (codeSource != null) ? codeSource.getLocation().toURI() : null;
			String path = (location != null) ? location.getSchemeSpecificPart() : null;
			if (path == null) {
				throw new IllegalStateException("Unable to determine code source archive");
			}
			File appJarFile = new File(path);
			if (!appJarFile.exists()) {
				throw new IllegalStateException("Unable to determine code source archive from " + appJarFile);
			}
//			JarFileArchive appJarArchive = new JarFileArchive(appJarFile);
			JarFile appJar=new JarFile(appJarFile);
			Manifest manifest = appJar.getManifest();
			if (manifest != null) {
				String classPathValue = manifest.getMainAttributes().getValue("Class-Path");
				if(classPathValue!=null && classPathValue.length()>0){
					List<String> classPathUrlStrs = Arrays.asList(classPathValue.split(" "));
					//用户根目录
					String userDir = SystemPropertyUtils.getProperty("user.dir");
					for(String classPathUrlStr : classPathUrlStrs){
						if(classPathUrlStr!=null && classPathUrlStr.length()>0){
							File cpJarFile = new File(userDir + "/" + classPathUrlStr.replace("placeholderplaceholderlib", "lib"));
							if(cpJarFile.exists()){
								System.out.println("+++++++++++++" + cpJarFile.getAbsolutePath() + "+++++++++++++");
								JarFileArchive appJarArchive = new JarFileArchive(cpJarFile);
								classPathJars.add(appJarArchive.getUrl());
							}
						}
					}
				}
			}


			for(URL classPathJarUrl : classPathJars){
				if(!hasLoaderJars.contains(classPathJarUrl)){
					needLoaderJars.add(classPathJarUrl);
				}
			}

			for(URL needLoaderJarUrl : needLoaderJars){
				Method add = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
				add.setAccessible(true);
				add.invoke(launchedURLClassLoader, needLoaderJarUrl);
			}
		}

		SpringApplication.run(DubboNacosProviderAPPlication.class,args);
		System.out.println(
		"////////////////////////////////////////////////////////////////////\n" +
		"//                          _ooOoo_                               //\n" +
		"//                         o8888888o                              //\n" +
		"//                         88\" . \"88                              //\n" +
		"//                         (| ^_^ |)                              //\n" +
		"//                         O\\  =  /O                              //\n" +
		"//                      ____/`---'\\____                           //\n" +
		"//                    .'  \\\\|     |//  `.                         //\n" +
		"//                   /  \\\\|||  :  |||//  \\                        //\n" +
		"//                  /  _||||| -:- |||||-  \\                       //\n" +
		"//                  |   | \\\\\\  -  /// |   |                       //\n" +
		"//                  | \\_|  ''\\---/''  |   |                       //\n" +
		"//                  \\  .-\\__  `-`  ___/-. /                       //\n" +
		"//                ___`. .'  /--.--\\  `. . ___                     //\n" +
		"//              .\"\" '<  `.___\\_<|>_/___.'  >'\"\".                  //\n" +
		"//            | | :  `- \\`.;`\\ _ /`;.`/ - ` : | |                 //\n" +
		"//            \\  \\ `-.   \\_ __\\ /__ _/   .-` /  /                 //\n" +
		"//      ========`-.____`-.___\\_____/___.-`____.-'========         //\n" +
		"//                           `=---='                              //\n" +
		"//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //\n" +
		"//             佛祖保佑       永不宕机      永无BUG                //\n" +
		"//(♥◠‿◠)ﾉﾞ ZTB workflow Client Successful Startup  ლ(´ڡ`ლ)ﾞ //");
	}

}